package com.clei.netty.util;

/**
 * 转义工具
 *
 * @author Y
 * @date 2022-04-20
 */
public class TransformUtil {

    /**
     * 0X7E
     */
    private static final byte E7 = 0X7E;

    /**
     * 0X7D
     */
    private static final byte D7 = 0X7D;

    /**
     * 0X01
     */
    private static final byte ONE = 0X01;

    /**
     * 0X02
     */
    private static final byte TWO = 0X02;

    /**
     * 转义
     * 0X7E -> 0X7D0X02
     * 0X7D -> 0X7D0X01
     *
     * @param data 原始数据
     * @return 转义后的数据
     */
    public static byte[] transform(byte[] data) {
        int length = data.length;
        for (byte b : data) {
            if (b == E7 || b == D7) {
                length++;
            }
        }
        byte[] res = new byte[length];
        for (int i = 0, j = 0; i < data.length; i++, j++) {
            byte b = data[i];
            if (b == E7) {
                res[j] = D7;
                res[++j] = TWO;
            } else if (b == D7) {
                res[j] = D7;
                res[++j] = ONE;
            } else {
                res[j] = b;
            }
        }
        return res;
    }

    /**
     * 还原
     * 0X7D0X02 -> 0X7E
     * 0X7D0X01 -> 0X7D
     *
     * @param data 转义后的数据
     * @return 原始数据
     */
    public static byte[] transformBack(byte[] data) {
        int length = data.length;
        for (int i = 0; i < data.length; i++) {
            byte b = data[i];
            if (b == D7 && (data[i + 1] == ONE || data[i + 1] == TWO)) {
                length--;
                i++;
            }
        }
        byte[] res = new byte[length];
        for (int i = 0, j = 0; i < data.length; i++, j++) {
            byte b = data[i];
            if (b == D7) {
                if (data[i + 1] == TWO) {
                    res[j] = E7;
                    i++;
                } else if (data[i + 1] == ONE) {
                    res[j] = D7;
                    i++;
                }
            } else {
                res[j] = b;
            }
        }
        return res;
    }
}
